Skip to content

Comments

fix: sync node.imgs for legacy context menu in Vue Nodes mode#8143

Merged
christian-byrne merged 4 commits intomainfrom
fix/sync-node-imgs-legacy-context-menu
Feb 19, 2026
Merged

fix: sync node.imgs for legacy context menu in Vue Nodes mode#8143
christian-byrne merged 4 commits intomainfrom
fix/sync-node-imgs-legacy-context-menu

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Jan 18, 2026

Summary

Fixes missing "Copy Image", "Open Image", "Save Image", and "Open in Mask Editor" context menu options on SaveImage nodes when Vue Nodes mode is enabled.

Changes

  • Add syncLegacyNodeImgs store method to sync loaded image elements to node.imgs
  • Call sync on image load in ImagePreview component
  • Simplify mask editor handling to call composable directly

Technical Details

  • Only runs when vueNodesMode is enabled (no impact on legacy mode)
  • Reuses already-loaded <img> element from Vue (no duplicate network requests)
  • Store owns the sync logic, component just hands off the element

Supersedes #7416

┆Issue is synchronized with this Notion page by Unito

Add syncLegacyNodeImgs store method to sync loaded image elements to
node.imgs for backwards compatibility with legacy systems (Copy Image,
Open Image, Save Image, Open in Mask Editor).

- Only runs when vueNodesMode is enabled
- Reuses already-loaded img element from Vue component (no duplicate loading)
- Store owns the sync logic, component just hands off the element
- Simplify mask editor handling to call composable directly

Fixes missing context menu options on SaveImage vue node.

Amp-Thread-ID: https://ampcode.com/threads/T-019bba3e-0ad8-754a-bd50-5cf17165d5a6
Co-authored-by: Amp <amp@ampcode.com>
@christian-byrne christian-byrne requested a review from a team as a code owner January 18, 2026 03:48
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 18, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 18, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Replaces command-based mask editor opening with a new useMaskEditor().openMaskEditor(node) call in the ImagePreview component, removes the local image element ref, and adds syncLegacyNodeImgs(nodeId, element, activeIndex) to the image preview store; tests and browser tests added for these flows.

Changes

Cohort / File(s) Summary
Vue Component
src/renderer/extensions/vueNodes/components/ImagePreview.vue
Removed the local image element ref and related setup; replaced useCommandStore usage with useMaskEditor().openMaskEditor(node); call nodeOutputStore.syncLegacyNodeImgs on image load; removed setupNodeForMaskEditor; updated imports.
Store Implementation
src/stores/imagePreviewStore.ts
Added syncLegacyNodeImgs(nodeId, element, activeIndex = 0) which, when LiteGraph.vueNodesMode is true, looks up the node and sets node.imgs = [element] and node.imageIndex = activeIndex; imported LiteGraph; exposed function from the store.
Store Tests
src/stores/imagePreviewStore.test.ts
Added LiteGraph mock and mockGetNodeById; extended createMockNode to accept overrides; comprehensive syncLegacyNodeImgs tests covering vueNodesMode on/off, numeric and string nodeId handling, missing node behavior, and activeIndex defaults; test lifecycle resets added.
Browser Tests
browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts
Added Playwright tests that enable VueNodes, load a widget workflow, drag/drop a 64×64 image onto a LoadImage node, verify image preview UI, test opening the mask editor from the preview button, and assert image-related context menu options.

Sequence Diagram

sequenceDiagram
    participant ImagePreview as ImagePreview.vue
    participant Handler as handleImageLoad / handleEditMask
    participant Store as nodeOutputStore
    participant Graph as LiteGraph.rootGraph
    participant Mask as useMaskEditor

    rect rgba(200,150,255,0.5)
    Note over ImagePreview,Graph: Image load → legacy node sync
    ImagePreview->>Handler: image loaded (element, nodeId, activeIndex)
    Handler->>Store: syncLegacyNodeImgs(nodeId, element, activeIndex)
    alt LiteGraph.vueNodesMode == true
        Store->>Graph: getNodeById(nodeId)
        Graph-->>Store: node (or null)
        opt node found
            Store->>Store: node.imgs = [element]\nnode.imageIndex = activeIndex
        end
    end
    end

    rect rgba(100,200,255,0.5)
    Note over ImagePreview,Mask: Open mask editor flow
    ImagePreview->>Handler: user clicks "Edit Mask" (with nodeId)
    Handler->>Mask: openMaskEditor(node)
    Mask->>Mask: initialize editor with node
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

"I hopped by the pixels, nose twitching with glee,
I synced up the old nodes so the images agree.
I nudged open the mask with a soft little tap,
Now masks and previews nap snug in my lap. 🐇✨"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: syncing node.imgs to fix legacy context menu options in Vue Nodes mode, which is the core objective of the PR.
Description check ✅ Passed The description includes all required sections from the template (Summary, Changes, Technical Details) and clearly explains what was changed, why, and technical implications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/sync-node-imgs-legacy-context-menu

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 02/18/2026, 11:29:58 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 18, 2026

Playwright: ❌ 518 passed, 2 failed · 4 flaky

❌ Failed Tests

📊 Browser Reports
  • chromium: View Report (✅ 506 / ❌ 2 / ⚠️ 4 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@coderabbitai coderabbitai bot requested review from DrJKL and Myestery January 18, 2026 03:49
@github-actions
Copy link

github-actions bot commented Jan 18, 2026

Bundle Size Report

Summary

  • Raw size: 20 MB baseline 20 MB — 🔴 +62 B
  • Gzip: 4.26 MB baseline 4.26 MB — 🔴 +163 B
  • Brotli: 3.31 MB baseline 3.31 MB — 🔴 +153 B
  • Bundles: 231 current • 231 baseline • 109 added / 109 removed

Category Glance
Data & Services 🔴 +267 B (2.16 MB) · Graph Workspace 🟢 -205 B (905 kB) · Vendor & Third-Party ⚪ 0 B (8.69 MB) · Other ⚪ 0 B (7.42 MB) · Panels & Settings ⚪ 0 B (427 kB) · Utilities & Hooks ⚪ 0 B (237 kB) · + 5 more

Per-category breakdown
App Entry Points — 21.7 kB (baseline 21.7 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BiEUGbUA.js (removed) 21.7 kB 🟢 -21.7 kB 🟢 -7.03 kB 🟢 -6.13 kB
assets/index-Bt8OfMvT.js (new) 21.7 kB 🔴 +21.7 kB 🔴 +7.03 kB 🔴 +6.1 kB

Status: 1 added / 1 removed

Graph Workspace — 905 kB (baseline 905 kB) • 🟢 -205 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-B9ax1Zj_.js (removed) 905 kB 🟢 -905 kB 🟢 -195 kB 🟢 -148 kB
assets/GraphView-CUMEPtPz.js (new) 905 kB 🔴 +905 kB 🔴 +195 kB 🔴 +148 kB

Status: 1 added / 1 removed

Views & Navigation — 69 kB (baseline 69 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-B4IZR28d.js (removed) 15.5 kB 🟢 -15.5 kB 🟢 -3.31 kB 🟢 -2.84 kB
assets/CloudSurveyView-DuAnd8Kw.js (new) 15.5 kB 🔴 +15.5 kB 🔴 +3.31 kB 🔴 +2.83 kB
assets/CloudLoginView-CAwLT7Wj.js (new) 10.1 kB 🔴 +10.1 kB 🔴 +2.95 kB 🔴 +2.59 kB
assets/CloudLoginView-t4oym2gh.js (removed) 10.1 kB 🟢 -10.1 kB 🟢 -2.94 kB 🟢 -2.58 kB
assets/UserCheckView-CXwh8w1y.js (removed) 8.41 kB 🟢 -8.41 kB 🟢 -2.23 kB 🟢 -1.95 kB
assets/UserCheckView-uugpDlfE.js (new) 8.41 kB 🔴 +8.41 kB 🔴 +2.23 kB 🔴 +1.95 kB
assets/CloudSignupView-CtAlkMre.js (new) 7.46 kB 🔴 +7.46 kB 🔴 +2.34 kB 🔴 +2.07 kB
assets/CloudSignupView-ho-TzsLX.js (removed) 7.46 kB 🟢 -7.46 kB 🟢 -2.34 kB 🟢 -2.07 kB
assets/CloudLayoutView-Bu-Etx7x.js (new) 6.48 kB 🔴 +6.48 kB 🔴 +2.12 kB 🔴 +1.85 kB
assets/CloudLayoutView-CA3b1PQy.js (removed) 6.48 kB 🟢 -6.48 kB 🟢 -2.12 kB 🟢 -1.85 kB
assets/CloudForgotPasswordView-CazWYAPS.js (new) 5.61 kB 🔴 +5.61 kB 🔴 +1.95 kB 🔴 +1.73 kB
assets/CloudForgotPasswordView-K2yGvZeP.js (removed) 5.61 kB 🟢 -5.61 kB 🟢 -1.95 kB 🟢 -1.75 kB
assets/CloudAuthTimeoutView--frGssbH.js (removed) 4.96 kB 🟢 -4.96 kB 🟢 -1.79 kB 🟢 -1.57 kB
assets/CloudAuthTimeoutView-n403yuJr.js (new) 4.96 kB 🔴 +4.96 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/CloudSubscriptionRedirectView-BGr14WuB.js (removed) 4.76 kB 🟢 -4.76 kB 🟢 -1.8 kB 🟢 -1.59 kB
assets/CloudSubscriptionRedirectView-CfQCH3AF.js (new) 4.76 kB 🔴 +4.76 kB 🔴 +1.8 kB 🔴 +1.59 kB
assets/UserSelectView-BTV1JdtO.js (new) 4.5 kB 🔴 +4.5 kB 🔴 +1.64 kB 🔴 +1.47 kB
assets/UserSelectView-CQK9v7jW.js (removed) 4.5 kB 🟢 -4.5 kB 🟢 -1.64 kB 🟢 -1.47 kB
assets/CloudSorryContactSupportView-Dt5tckIJ.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-Dw2vG5GB.js 296 B 296 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 9 added / 9 removed

Panels & Settings — 427 kB (baseline 427 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SecretsPanel-B-fj76LB.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +5.3 kB 🔴 +4.66 kB
assets/SecretsPanel-DDWUtGKY.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -5.3 kB 🟢 -4.67 kB
assets/LegacyCreditsPanel-B5TrMq-9.js (removed) 20.7 kB 🟢 -20.7 kB 🟢 -5.58 kB 🟢 -4.91 kB
assets/LegacyCreditsPanel-DdzRBa7x.js (new) 20.7 kB 🔴 +20.7 kB 🔴 +5.59 kB 🔴 +4.91 kB
assets/SubscriptionPanel-Datg8RIr.js (new) 18.7 kB 🔴 +18.7 kB 🔴 +4.74 kB 🔴 +4.2 kB
assets/SubscriptionPanel-kV0AvbEz.js (removed) 18.7 kB 🟢 -18.7 kB 🟢 -4.74 kB 🟢 -4.18 kB
assets/KeybindingPanel-Ck7cnOgB.js (removed) 12.4 kB 🟢 -12.4 kB 🟢 -3.59 kB 🟢 -3.17 kB
assets/KeybindingPanel-D2kJ7ME0.js (new) 12.4 kB 🔴 +12.4 kB 🔴 +3.59 kB 🔴 +3.19 kB
assets/ExtensionPanel-bpoMdzRV.js (removed) 9.43 kB 🟢 -9.43 kB 🟢 -2.67 kB 🟢 -2.37 kB
assets/ExtensionPanel-XJs5oBLN.js (new) 9.43 kB 🔴 +9.43 kB 🔴 +2.67 kB 🔴 +2.37 kB
assets/AboutPanel-kzHAO7Tj.js (new) 8.53 kB 🔴 +8.53 kB 🔴 +2.44 kB 🔴 +2.2 kB
assets/AboutPanel-LCqoDpN2.js (removed) 8.53 kB 🟢 -8.53 kB 🟢 -2.44 kB 🟢 -2.21 kB
assets/ServerConfigPanel-BBkWN3Lg.js (removed) 6.5 kB 🟢 -6.5 kB 🟢 -2.13 kB 🟢 -1.91 kB
assets/ServerConfigPanel-CLLvVDkc.js (new) 6.5 kB 🔴 +6.5 kB 🔴 +2.13 kB 🔴 +1.94 kB
assets/UserPanel-BBuZTY8a.js (new) 6.21 kB 🔴 +6.21 kB 🔴 +2.02 kB 🔴 +1.77 kB
assets/UserPanel-YI6jKXnp.js (removed) 6.21 kB 🟢 -6.21 kB 🟢 -2.02 kB 🟢 -1.76 kB
assets/cloudRemoteConfig-DIv1nGek.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -727 B 🟢 -627 B
assets/cloudRemoteConfig-WIAxD-0o.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +729 B 🔴 +629 B
assets/refreshRemoteConfig-DVYuuCoQ.js (new) 1.14 kB 🔴 +1.14 kB 🔴 +521 B 🔴 +458 B
assets/refreshRemoteConfig-kBOn1Axr.js (removed) 1.14 kB 🟢 -1.14 kB 🟢 -518 B 🟢 -457 B
assets/config-CH_cdA2N.js 996 B 996 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BPLxqAe3.js 29.8 kB 29.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BUIbWSEk.js 28 kB 28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C0d1Q_Kv.js 27.1 kB 27.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CAXBW2_0.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cjk3QxCD.js 37.6 kB 37.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CrmQjb0f.js 31.6 kB 31.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D1AmG0ju.js 23.3 kB 23.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D6ltw1Hs.js 29.2 kB 29.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DqZYOPVX.js 23.9 kB 23.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DubbIIfi.js 28.1 kB 28.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-wh8yrcgf.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 10 added / 10 removed

User & Accounts — 16.1 kB (baseline 16.1 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-D4coMMFD.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.18 kB 🔴 +987 B
assets/auth-Dl-HIber.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.18 kB 🟢 -984 B
assets/SignUpForm-0_lw73mQ.js (removed) 3.01 kB 🟢 -3.01 kB 🟢 -1.23 kB 🟢 -1.1 kB
assets/SignUpForm-BqzRnte-.js (new) 3.01 kB 🔴 +3.01 kB 🔴 +1.23 kB 🔴 +1.1 kB
assets/UpdatePasswordContent-BHhDcxKF.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -1.09 kB 🟢 -961 B
assets/UpdatePasswordContent-C59mu6Y0.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.09 kB 🔴 +964 B
assets/firebaseAuthStore-BT-2yZcL.js (removed) 837 B 🟢 -837 B 🟢 -403 B 🟢 -361 B
assets/firebaseAuthStore-C4iK-Hos.js (new) 837 B 🔴 +837 B 🔴 +407 B 🔴 +362 B
assets/auth-Bo0uaOOK.js (removed) 357 B 🟢 -357 B 🟢 -222 B 🟢 -195 B
assets/auth-DTk70XEz.js (new) 357 B 🔴 +357 B 🔴 +222 B 🔴 +187 B
assets/PasswordFields-PRmvmozX.js 4.51 kB 4.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspaceProfilePic-BbVtvHlF.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Editors & Dialogs — 785 B (baseline 785 B) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-BeUFd4Hi.js (new) 785 B 🔴 +785 B 🔴 +399 B 🔴 +348 B
assets/useSubscriptionDialog-Bz7d5yx9.js (removed) 785 B 🟢 -785 B 🟢 -395 B 🟢 -350 B

Status: 1 added / 1 removed

UI Components — 36.6 kB (baseline 36.6 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useTerminalTabs-CaJZi6Xz.js (removed) 9.89 kB 🟢 -9.89 kB 🟢 -3.42 kB 🟢 -3.02 kB
assets/useTerminalTabs-CCCku8fP.js (new) 9.89 kB 🔴 +9.89 kB 🔴 +3.42 kB 🔴 +3.02 kB
assets/ComfyQueueButton-Cbw-zR5P.js (new) 7.17 kB 🔴 +7.17 kB 🔴 +2.32 kB 🔴 +2.07 kB
assets/ComfyQueueButton-rlEjEIaK.js (removed) 7.17 kB 🟢 -7.17 kB 🟢 -2.31 kB 🟢 -2.07 kB
assets/SubscribeButton-BOweBQdp.js (new) 2.35 kB 🔴 +2.35 kB 🔴 +1.02 kB 🔴 +885 B
assets/SubscribeButton-D7V7JFsu.js (removed) 2.35 kB 🟢 -2.35 kB 🟢 -1.02 kB 🟢 -887 B
assets/cloudFeedbackTopbarButton-BPCf20vq.js (removed) 1.64 kB 🟢 -1.64 kB 🟢 -875 B 🟢 -779 B
assets/cloudFeedbackTopbarButton-DVfZ4_BX.js (new) 1.64 kB 🔴 +1.64 kB 🔴 +876 B 🔴 +775 B
assets/ComfyQueueButton-BUqtzRY-.js (new) 842 B 🔴 +842 B 🔴 +412 B 🔴 +363 B
assets/ComfyQueueButton-VIo5UorP.js (removed) 842 B 🟢 -842 B 🟢 -409 B 🟢 -365 B
assets/Button-BSbVSHEC.js 2.98 kB 2.98 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-QozxHIt4.js 1.24 kB 1.24 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-CFCM1GaS.js 7.45 kB 7.45 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-BG_h7fX0.js 1.17 kB 1.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-C-W7fvtO.js 1.84 kB 1.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Data & Services — 2.16 MB (baseline 2.16 MB) • 🔴 +267 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-DHP14Llx.js (new) 1.38 MB 🔴 +1.38 MB 🔴 +311 kB 🔴 +240 kB
assets/dialogService-CzToVyoa.js (removed) 1.38 MB 🟢 -1.38 MB 🟢 -311 kB 🟢 -240 kB
assets/api-CSKe5VI6.js (new) 647 kB 🔴 +647 kB 🔴 +146 kB 🔴 +117 kB
assets/api-G3buPaUX.js (removed) 647 kB 🟢 -647 kB 🟢 -146 kB 🟢 -117 kB
assets/load3dService-DRerWGVw.js (new) 91 kB 🔴 +91 kB 🔴 +19.1 kB 🔴 +16.4 kB
assets/load3dService-DxrSdD5-.js (removed) 91 kB 🟢 -91 kB 🟢 -19.1 kB 🟢 -16.4 kB
assets/systemStatsStore-Bkc65GC6.js (new) 12.2 kB 🔴 +12.2 kB 🔴 +4.27 kB 🔴 +3.75 kB
assets/systemStatsStore-DzbABsdo.js (removed) 12.2 kB 🟢 -12.2 kB 🟢 -4.26 kB 🟢 -3.74 kB
assets/releaseStore-B2wAVTcD.js (new) 7.96 kB 🔴 +7.96 kB 🔴 +2.22 kB 🔴 +1.95 kB
assets/releaseStore-v1cj7S4Q.js (removed) 7.96 kB 🟢 -7.96 kB 🟢 -2.22 kB 🟢 -1.95 kB
assets/keybindingService-2z9GWgAk.js (removed) 6.57 kB 🟢 -6.57 kB 🟢 -1.72 kB 🟢 -1.49 kB
assets/keybindingService-Bd2ksKo5.js (new) 6.57 kB 🔴 +6.57 kB 🔴 +1.72 kB 🔴 +1.49 kB
assets/bootstrapStore-C847N-Sg.js (removed) 2.08 kB 🟢 -2.08 kB 🟢 -875 B 🟢 -793 B
assets/bootstrapStore-D7lKuAxD.js (new) 2.08 kB 🔴 +2.08 kB 🔴 +876 B 🔴 +796 B
assets/userStore-BDSDHu9M.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -720 B 🟢 -675 B
assets/userStore-CfsN5A1Y.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +721 B 🔴 +673 B
assets/audioService-BhmRTo8k.js (new) 1.73 kB 🔴 +1.73 kB 🔴 +848 B 🔴 +727 B
assets/audioService-D9U7_blV.js (removed) 1.73 kB 🟢 -1.73 kB 🟢 -848 B 🟢 -725 B
assets/releaseStore-B-WtmLGJ.js (new) 809 B 🔴 +809 B 🔴 +403 B 🔴 +353 B
assets/releaseStore-CGO0phkD.js (removed) 809 B 🟢 -809 B 🟢 -402 B 🟢 -358 B
assets/settingStore-aOQZbbFg.js (new) 793 B 🔴 +793 B 🔴 +406 B 🔴 +355 B
assets/settingStore-D82P2Gwe.js (removed) 793 B 🟢 -793 B 🟢 -402 B 🟢 -354 B
assets/workflowDraftStore-BydCAjOE.js (new) 785 B 🔴 +785 B 🔴 +399 B 🔴 +351 B
assets/workflowDraftStore-DcEty3KW.js (removed) 785 B 🟢 -785 B 🟢 -396 B 🟢 -353 B
assets/dialogService-Dcbzq7Us.js (removed) 774 B 🟢 -774 B 🟢 -387 B 🟢 -349 B
assets/dialogService-OUtff6UX.js (new) 774 B 🔴 +774 B 🔴 +390 B 🔴 +349 B
assets/dialogStore-DqEczCra.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-DUe9-l1S.js 2.32 kB 2.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 13 added / 13 removed

Utilities & Hooks — 237 kB (baseline 237 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-BwisPbOU.js (new) 178 kB 🔴 +178 kB 🔴 +39.4 kB 🔴 +32.8 kB
assets/useConflictDetection-BxdlsAh7.js (removed) 178 kB 🟢 -178 kB 🟢 -39.4 kB 🟢 -32.8 kB
assets/useLoad3d-BzE6iXmk.js (removed) 14.6 kB 🟢 -14.6 kB 🟢 -3.63 kB 🟢 -3.21 kB
assets/useLoad3d-zd9Ql9kx.js (new) 14.6 kB 🔴 +14.6 kB 🔴 +3.63 kB 🔴 +3.21 kB
assets/useLoad3dViewer-B7xhNfg_.js (new) 14.1 kB 🔴 +14.1 kB 🔴 +3.14 kB 🔴 +2.79 kB
assets/useLoad3dViewer-BG4eXGNu.js (removed) 14.1 kB 🟢 -14.1 kB 🟢 -3.15 kB 🟢 -2.79 kB
assets/useFeatureFlags-CiPDeZDg.js (new) 3.5 kB 🔴 +3.5 kB 🔴 +1.08 kB 🔴 +926 B
assets/useFeatureFlags-FkG-exBc.js (removed) 3.5 kB 🟢 -3.5 kB 🟢 -1.08 kB 🟢 -927 B
assets/useWorkspaceUI-BlhfHS4K.js (new) 3 kB 🔴 +3 kB 🔴 +822 B 🔴 +703 B
assets/useWorkspaceUI-BUe_OJVE.js (removed) 3 kB 🟢 -3 kB 🟢 -822 B 🟢 -696 B
assets/useSubscriptionCredits-CybfBe6D.js (new) 2.75 kB 🔴 +2.75 kB 🔴 +1.04 kB 🔴 +900 B
assets/useSubscriptionCredits-nLppWaEX.js (removed) 2.75 kB 🟢 -2.75 kB 🟢 -1.04 kB 🟢 -901 B
assets/subscriptionCheckoutUtil-B0tTj6W0.js (new) 2.53 kB 🔴 +2.53 kB 🔴 +1.06 kB 🔴 +953 B
assets/subscriptionCheckoutUtil-CIO-N4CK.js (removed) 2.53 kB 🟢 -2.53 kB 🟢 -1.06 kB 🟢 -961 B
assets/useErrorHandling-9wDdGMXn.js (removed) 1.47 kB 🟢 -1.47 kB 🟢 -611 B 🟢 -517 B
assets/useErrorHandling-CaHlSxyn.js (new) 1.47 kB 🔴 +1.47 kB 🔴 +611 B 🔴 +517 B
assets/useWorkspaceSwitch-84mKXcxh.js (removed) 1.25 kB 🟢 -1.25 kB 🟢 -543 B 🟢 -489 B
assets/useWorkspaceSwitch-DmcL1IzI.js (new) 1.25 kB 🔴 +1.25 kB 🔴 +544 B 🔴 +483 B
assets/useLoad3d-BLqPvIUg.js (removed) 908 B 🟢 -908 B 🟢 -439 B 🟢 -395 B
assets/useLoad3d-C7vWnYw6.js (new) 908 B 🔴 +908 B 🔴 +441 B 🔴 +393 B
assets/useLoad3dViewer-CF3LsomA.js (new) 887 B 🔴 +887 B 🔴 +429 B 🔴 +384 B
assets/useLoad3dViewer-CkqSKKdF.js (removed) 887 B 🟢 -887 B 🟢 -423 B 🟢 -384 B
assets/audioUtils-C3iv5DoS.js (new) 858 B 🔴 +858 B 🔴 +500 B 🔴 +406 B
assets/audioUtils-CAtNmhjC.js (removed) 858 B 🟢 -858 B 🟢 -499 B 🟢 -402 B
assets/useCurrentUser-BubVcADY.js (removed) 771 B 🟢 -771 B 🟢 -391 B 🟢 -348 B
assets/useCurrentUser-Ch2-iN0D.js (new) 771 B 🔴 +771 B 🔴 +393 B 🔴 +348 B
assets/_plugin-vue_export-helper-BYZQdlgo.js 315 B 315 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-CZQOOTdR.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/envUtil-C9Y4v_FL.js 466 B 466 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-Dct6u2-O.js 1.56 kB 1.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SkeletonUtils-CsnHjXS0.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCopyToClipboard-N_vzUkgQ.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useExternalLink-B5xMNx28.js 1.66 kB 1.66 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 13 added / 13 removed

Vendor & Third-Party — 8.69 MB (baseline 8.69 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-axios-C4mPrLmU.js 70.3 kB 70.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-chart-l-KY-tZQ.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-firebase-BvMr43CG.js 836 kB 836 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-i18n-cR3vmlFu.js 131 kB 131 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-markdown-oliHT-H5.js 102 kB 102 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-DIFkoP9Z.js 1.52 MB 1.52 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-DbhsokLF.js 1.73 MB 1.73 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-DAi_xVZa.js 255 kB 255 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-sentry-SQwstEKc.js 182 kB 182 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-ueviNA60.js 1.8 MB 1.8 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DN5cees9.js 625 kB 625 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-core-BjA-tjXK.js 311 kB 311 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-DcEOrMQz.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-CWHPCody.js 374 kB 374 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-CP_4YO8u.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-zod-DcCUUPIi.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.42 MB (baseline 7.42 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-H2BR16Rk.js (new) 72.5 kB 🔴 +72.5 kB 🔴 +18.7 kB 🔴 +16 kB
assets/core-kWNOSVZc.js (removed) 72.5 kB 🟢 -72.5 kB 🟢 -18.7 kB 🟢 -16 kB
assets/groupNode-CjtFFJFN.js (new) 72.1 kB 🔴 +72.1 kB 🔴 +17.7 kB 🔴 +15.6 kB
assets/groupNode-CuJ5Rojj.js (removed) 72.1 kB 🟢 -72.1 kB 🟢 -17.7 kB 🟢 -15.6 kB
assets/WidgetSelect-BwfCCSEA.js (removed) 57.8 kB 🟢 -57.8 kB 🟢 -12.3 kB 🟢 -10.6 kB
assets/WidgetSelect-CrYf68x9.js (new) 57.8 kB 🔴 +57.8 kB 🔴 +12.3 kB 🔴 +10.6 kB
assets/SubscriptionRequiredDialogContentWorkspace-BrvAOF3y.js (removed) 45.9 kB 🟢 -45.9 kB 🟢 -8.58 kB 🟢 -7.44 kB
assets/SubscriptionRequiredDialogContentWorkspace-ZvOjvNBc.js (new) 45.9 kB 🔴 +45.9 kB 🔴 +8.58 kB 🔴 +7.42 kB
assets/Load3DControls-B_lSP4JH.js (new) 30.9 kB 🔴 +30.9 kB 🔴 +5.34 kB 🔴 +4.64 kB
assets/Load3DControls-CRXObUk5.js (removed) 30.9 kB 🟢 -30.9 kB 🟢 -5.34 kB 🟢 -4.64 kB
assets/WorkspacePanelContent-CEUvsktN.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.13 kB 🔴 +5.39 kB
assets/WorkspacePanelContent-CZegjn79.js (removed) 29.3 kB 🟢 -29.3 kB 🟢 -6.12 kB 🟢 -5.38 kB
assets/SubscriptionRequiredDialogContent-D2lxd7dv.js (new) 26.2 kB 🔴 +26.2 kB 🔴 +6.59 kB 🔴 +5.81 kB
assets/SubscriptionRequiredDialogContent-DeOZzbBz.js (removed) 26.2 kB 🟢 -26.2 kB 🟢 -6.59 kB 🟢 -5.8 kB
assets/Load3dViewerContent-BTynn55W.js (new) 23.1 kB 🔴 +23.1 kB 🔴 +5.19 kB 🔴 +4.5 kB
assets/Load3dViewerContent-CU8aMdBt.js (removed) 23.1 kB 🟢 -23.1 kB 🟢 -5.19 kB 🟢 -4.5 kB
assets/MissingNodesContent-C5eja7kq.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.76 kB 🟢 -5.09 kB
assets/MissingNodesContent-DuxmLi-5.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.76 kB 🔴 +5.1 kB
assets/WidgetImageCrop-BPoirSZ4.js (removed) 22.1 kB 🟢 -22.1 kB 🟢 -5.51 kB 🟢 -4.84 kB
assets/WidgetImageCrop-BYPZdiTe.js (new) 22.1 kB 🔴 +22.1 kB 🔴 +5.51 kB 🔴 +4.85 kB
assets/SubscriptionPanelContentWorkspace-DcJqckDf.js (new) 21.6 kB 🔴 +21.6 kB 🔴 +5.02 kB 🔴 +4.43 kB
assets/SubscriptionPanelContentWorkspace-FyKDuV8i.js (removed) 21.6 kB 🟢 -21.6 kB 🟢 -5.02 kB 🟢 -4.43 kB
assets/CurrentUserPopoverWorkspace-BikvuDcm.js (new) 19.9 kB 🔴 +19.9 kB 🔴 +4.88 kB 🔴 +4.35 kB
assets/CurrentUserPopoverWorkspace-DhpRNUzh.js (removed) 19.9 kB 🟢 -19.9 kB 🟢 -4.88 kB 🟢 -4.36 kB
assets/SignInContent-BWK5Ydnd.js (new) 19 kB 🔴 +19 kB 🔴 +4.81 kB 🔴 +4.21 kB
assets/SignInContent-DnkzCusq.js (removed) 19 kB 🟢 -19 kB 🟢 -4.81 kB 🟢 -4.22 kB
assets/WidgetRecordAudio-Bfe6hch_.js (new) 17.4 kB 🔴 +17.4 kB 🔴 +4.97 kB 🔴 +4.44 kB
assets/WidgetRecordAudio-DdeJBP7z.js (removed) 17.4 kB 🟢 -17.4 kB 🟢 -4.96 kB 🟢 -4.43 kB
assets/MissingModelsWarning-B3nye3bd.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -4.7 kB 🟢 -4.17 kB
assets/MissingModelsWarning-Cd9sw_RF.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +4.7 kB 🔴 +4.18 kB
assets/Load3D-BWzrmSBv.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +4.04 kB 🔴 +3.53 kB
assets/Load3D-Cg1I1zRH.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -4.04 kB 🟢 -3.52 kB
assets/WidgetInputNumber-BmosNHsK.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +4.26 kB 🔴 +3.81 kB
assets/WidgetInputNumber-ChjwNvrs.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -4.26 kB 🟢 -3.79 kB
assets/load3d-DjSMF1kY.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -4.2 kB 🟢 -3.64 kB
assets/load3d-DlAceDYb.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +4.2 kB 🔴 +3.65 kB
assets/AudioPreviewPlayer-DTGjLjIF.js (removed) 10.9 kB 🟢 -10.9 kB 🟢 -3.21 kB 🟢 -2.88 kB
assets/AudioPreviewPlayer-sSI-27SO.js (new) 10.9 kB 🔴 +10.9 kB 🔴 +3.21 kB 🔴 +2.87 kB
assets/NodeConflictDialogContent-3-ZMJsx9.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.36 kB 🔴 +2.09 kB
assets/NodeConflictDialogContent-CDGOAnPO.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.36 kB 🟢 -2.07 kB
assets/changeTracker-C3fl0K_2.js (removed) 9.38 kB 🟢 -9.38 kB 🟢 -2.89 kB 🟢 -2.54 kB
assets/changeTracker-DF_G-yhf.js (new) 9.38 kB 🔴 +9.38 kB 🔴 +2.89 kB 🔴 +2.55 kB
assets/nodeTemplates-BMAO5QYV.js (removed) 9.35 kB 🟢 -9.35 kB 🟢 -3.28 kB 🟢 -2.87 kB
assets/nodeTemplates-CCJDvrfu.js (new) 9.35 kB 🔴 +9.35 kB 🔴 +3.28 kB 🔴 +2.87 kB
assets/MissingNodesFooter-BFz01DtY.js (removed) 7.54 kB 🟢 -7.54 kB 🟢 -2.47 kB 🟢 -2.21 kB
assets/MissingNodesFooter-D0io10Qj.js (new) 7.54 kB 🔴 +7.54 kB 🔴 +2.47 kB 🔴 +2.2 kB
assets/InviteMemberDialogContent-0ShtuIj7.js (new) 7.44 kB 🔴 +7.44 kB 🔴 +2.31 kB 🔴 +2.03 kB
assets/InviteMemberDialogContent-B-e31tm9.js (removed) 7.44 kB 🟢 -7.44 kB 🟢 -2.31 kB 🟢 -2.02 kB
assets/WidgetWithControl-BZ0HIg1t.js (removed) 7.08 kB 🟢 -7.08 kB 🟢 -2.65 kB 🟢 -2.36 kB
assets/WidgetWithControl-Ds_eRPY9.js (new) 7.08 kB 🔴 +7.08 kB 🔴 +2.65 kB 🔴 +2.36 kB
assets/Load3DConfiguration-BNFcgVu0.js (removed) 6.27 kB 🟢 -6.27 kB 🟢 -1.91 kB 🟢 -1.68 kB
assets/Load3DConfiguration-CbdrpTZU.js (new) 6.27 kB 🔴 +6.27 kB 🔴 +1.91 kB 🔴 +1.68 kB
assets/CreateWorkspaceDialogContent-5pu3Wpsy.js (removed) 5.58 kB 🟢 -5.58 kB 🟢 -2.01 kB 🟢 -1.76 kB
assets/CreateWorkspaceDialogContent-D_wOynPj.js (new) 5.58 kB 🔴 +5.58 kB 🔴 +2.01 kB 🔴 +1.75 kB
assets/EditWorkspaceDialogContent-tfIdqAYt.js (new) 5.38 kB 🔴 +5.38 kB 🔴 +1.96 kB 🔴 +1.72 kB
assets/EditWorkspaceDialogContent-U6zGF-FU.js (removed) 5.38 kB 🟢 -5.38 kB 🟢 -1.96 kB 🟢 -1.72 kB
assets/ValueControlPopover-BRM66qss.js (new) 4.97 kB 🔴 +4.97 kB 🔴 +1.79 kB 🔴 +1.59 kB
assets/ValueControlPopover-CkKQFmD_.js (removed) 4.97 kB 🟢 -4.97 kB 🟢 -1.79 kB 🟢 -1.6 kB
assets/Preview3d-C1zGsfRn.js (removed) 4.86 kB 🟢 -4.86 kB 🟢 -1.58 kB 🟢 -1.39 kB
assets/Preview3d-CHZDIwUX.js (new) 4.86 kB 🔴 +4.86 kB 🔴 +1.59 kB 🔴 +1.39 kB
assets/CancelSubscriptionDialogContent-CM-2uoag.js (new) 4.85 kB 🔴 +4.85 kB 🔴 +1.8 kB 🔴 +1.58 kB
assets/CancelSubscriptionDialogContent-DHFm0GZ1.js (removed) 4.85 kB 🟢 -4.85 kB 🟢 -1.8 kB 🟢 -1.58 kB
assets/DeleteWorkspaceDialogContent-BOYmQrPU.js (new) 4.29 kB 🔴 +4.29 kB 🔴 +1.65 kB 🔴 +1.43 kB
assets/DeleteWorkspaceDialogContent-gan-vXUI.js (removed) 4.29 kB 🟢 -4.29 kB 🟢 -1.65 kB 🟢 -1.44 kB
assets/LeaveWorkspaceDialogContent-D1zUcz51.js (removed) 4.12 kB 🟢 -4.12 kB 🟢 -1.6 kB 🟢 -1.39 kB
assets/LeaveWorkspaceDialogContent-DMn5AHnD.js (new) 4.12 kB 🔴 +4.12 kB 🔴 +1.6 kB 🔴 +1.39 kB
assets/RemoveMemberDialogContent-4SRZX7iX.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.55 kB 🔴 +1.35 kB
assets/RemoveMemberDialogContent-tcmdXXgb.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.55 kB 🟢 -1.35 kB
assets/RevokeInviteDialogContent-CbY-UNPw.js (new) 4.01 kB 🔴 +4.01 kB 🔴 +1.56 kB 🔴 +1.37 kB
assets/RevokeInviteDialogContent-DwOSbSl5.js (removed) 4.01 kB 🟢 -4.01 kB 🟢 -1.56 kB 🟢 -1.37 kB
assets/InviteMemberUpsellDialogContent-BW-CNLac.js (new) 3.88 kB 🔴 +3.88 kB 🔴 +1.42 kB 🔴 +1.25 kB
assets/InviteMemberUpsellDialogContent-DmCwx_Ok.js (removed) 3.88 kB 🟢 -3.88 kB 🟢 -1.42 kB 🟢 -1.25 kB
assets/saveMesh-BCD4iEhw.js (new) 3.43 kB 🔴 +3.43 kB 🔴 +1.48 kB 🔴 +1.31 kB
assets/saveMesh-Da7l1fjM.js (removed) 3.43 kB 🟢 -3.43 kB 🟢 -1.48 kB 🟢 -1.31 kB
assets/cloudSessionCookie-DmJdGiSf.js (removed) 3.15 kB 🟢 -3.15 kB 🟢 -1.1 kB 🟢 -969 B
assets/cloudSessionCookie-KHhW-ZVE.js (new) 3.15 kB 🔴 +3.15 kB 🔴 +1.1 kB 🔴 +979 B
assets/GlobalToast-B3JoWcg_.js (removed) 2.91 kB 🟢 -2.91 kB 🟢 -1.21 kB 🟢 -1.03 kB
assets/GlobalToast-DVSReLQX.js (new) 2.91 kB 🔴 +2.91 kB 🔴 +1.21 kB 🔴 +1.03 kB
assets/SubscribeToRun-CAqM2oH4.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +1.01 kB 🔴 +899 B
assets/SubscribeToRun-CU3pLljN.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -1.01 kB 🟢 -890 B
assets/CloudRunButtonWrapper-B2lIImQk.js (removed) 1.72 kB 🟢 -1.72 kB 🟢 -802 B 🟢 -731 B
assets/CloudRunButtonWrapper-CbHVhRKg.js (new) 1.72 kB 🔴 +1.72 kB 🔴 +804 B 🔴 +727 B
assets/cloudBadges--JQN-Kn5.js (removed) 1.42 kB 🟢 -1.42 kB 🟢 -725 B 🟢 -628 B
assets/cloudBadges-Dz9Zcngn.js (new) 1.42 kB 🔴 +1.42 kB 🔴 +725 B 🔴 +622 B
assets/cloudSubscription-BJiCVqqH.js (new) 1.38 kB 🔴 +1.38 kB 🔴 +680 B 🔴 +585 B
assets/cloudSubscription-S-C3NLfb.js (removed) 1.38 kB 🟢 -1.38 kB 🟢 -678 B 🟢 -587 B
assets/Load3D-CWlSwJBO.js (removed) 1.12 kB 🟢 -1.12 kB 🟢 -511 B 🟢 -454 B
assets/Load3D-DIzr2bX4.js (new) 1.12 kB 🔴 +1.12 kB 🔴 +515 B 🔴 +459 B
assets/nightlyBadges-D3JJQlok.js (removed) 1.05 kB 🟢 -1.05 kB 🟢 -550 B 🟢 -492 B
assets/nightlyBadges-D6tUaA17.js (new) 1.05 kB 🔴 +1.05 kB 🔴 +553 B 🔴 +492 B
assets/Load3dViewerContent-C_jNtBfZ.js (removed) 1.04 kB 🟢 -1.04 kB 🟢 -481 B 🟢 -434 B
assets/Load3dViewerContent-CqdY_3hm.js (new) 1.04 kB 🔴 +1.04 kB 🔴 +486 B 🔴 +435 B
assets/SubscriptionPanelContentWorkspace-BnVqrTlK.js (new) 979 B 🔴 +979 B 🔴 +455 B 🔴 +398 B
assets/SubscriptionPanelContentWorkspace-R8YtTfmn.js (removed) 979 B 🟢 -979 B 🟢 -454 B 🟢 -398 B
assets/changeTracker-cRULF6N9.js (new) 806 B 🔴 +806 B 🔴 +403 B 🔴 +353 B
assets/changeTracker-DZ9vmYDl.js (removed) 806 B 🟢 -806 B 🟢 -402 B 🟢 -353 B
assets/WidgetLegacy-D2_pACI1.js (new) 794 B 🔴 +794 B 🔴 +405 B 🔴 +350 B
assets/WidgetLegacy-D3Vg0ghJ.js (removed) 794 B 🟢 -794 B 🟢 -401 B 🟢 -353 B
assets/graphHasMissingNodes-DAkc-6JP.js (new) 761 B 🔴 +761 B 🔴 +374 B 🔴 +316 B
assets/graphHasMissingNodes-mJxQvkt8.js (removed) 761 B 🟢 -761 B 🟢 -373 B 🟢 -318 B
assets/WidgetInputNumber-3a3YSQWa.js (new) 392 B 🔴 +392 B 🔴 +231 B 🔴 +200 B
assets/WidgetInputNumber-CP6RMBKJ.js (removed) 392 B 🟢 -392 B 🟢 -231 B 🟢 -211 B
assets/AnimationControls-uhOvrOXP.js 4.61 kB 4.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ApiNodesSignInContent--Xr4RxpM.js 2.69 kB 2.69 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auto-Bt3L7FBS.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/BaseViewTemplate--dbbFEs2.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/comfy-logo-single-BcOH_oP5.js 198 B 198 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyOrgHeader-CmrP3hho.js 910 B 910 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BE-vRwJl.js 16.6 kB 16.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BGHyTYD4.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bh57dtIu.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BhnFE3Dq.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C0TQG5MC.js 15.8 kB 15.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CauhF9Qg.js 17.1 kB 17.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D_1Nwml0.js 16.3 kB 16.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D6_SlWq_.js 18.4 kB 18.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DDnyk4ZD.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Xb1k_0Gj.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-yQtLjIyn.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/constants-ogISyp4e.js 579 B 579 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-B37HEt57.js 199 B 199 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-DReDPbev.js 503 kB 503 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeContent-Cbt6jZyc.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeFooter-CsC-FYf6.js 1.88 kB 1.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeHeader-C52A0tqP.js 1.08 kB 1.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage-hkB_HS4m.js 12.3 kB 12.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bq33klKY.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BSrK10sS.js 120 kB 120 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C7kc0UfI.js 119 kB 119 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cndduh31.js 138 kB 138 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cp0fA684.js 189 kB 189 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-D4Cj1GDq.js 136 kB 136 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DaCNhwIS.js 140 kB 140 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DQ_OxQ4G.js 135 kB 135 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-HM49HWUY.js 169 kB 169 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-KjqrTSvt.js 156 kB 156 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-O2EnFePa.js 164 kB 164 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-BHB5UVIn.js 1.82 kB 1.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-BYoymEsG.js 1.43 kB 1.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-DVg0EyQw.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-CoCFfqkW.js 2.23 kB 2.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesHeader-JfpleXg9.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictFooter-DhyemNV0.js 2.37 kB 2.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictHeader-DgbhznVf.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BHDxacOt.js 375 kB 375 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BzxC3xA2.js 345 kB 345 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C92z7Jao.js 461 kB 461 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CMJNOW2W.js 375 kB 375 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CPxgLLao.js 423 kB 423 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Curz6Nvc.js 368 kB 368 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DkB_F-Cq.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DS2DqIep.js 379 kB 379 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-mOwNzkna.js 390 kB 390 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-NvVROHN6.js 422 kB 422 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-WX8gf_Dw.js 372 kB 372 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-BlNc6I0i.js 665 B 665 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-DLICfi3-.js 1.97 kB 1.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SelectValue-BLaUzhId.js 8.94 kB 8.94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/signInSchema-p9VvHm9M.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-C8KGUioc.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/src-D5pbLGY2.js 251 B 251 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/telemetry-zZf2dHJ2.js 226 B 226 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-DT3N7am7.js 204 B 204 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-DTUjK0ZE.js 445 B 445 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-DMPeCuhp.js 3.91 kB 3.91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-F8leYtSX.js 131 B 131 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-BDCRAbXS.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-DfUBpgxw.js 2.9 kB 2.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-7qXE9PZk.js 3.61 kB 3.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-CeaLzXAr.js 3.1 kB 3.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-BQ_QzI-O.js 1.86 kB 1.86 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-CvLvf7SF.js 1.95 kB 1.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-wIs8y1Ja.js 2.88 kB 2.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-C9FcIgiN.js 1.1 kB 1.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-DurObIpO.js 3.18 kB 3.18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-D4M7QPIz.js 2.5 kB 2.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-DhbPR9pT.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 51 added / 51 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/stores/imagePreviewStore.test.ts (1)

26-31: Prefer Partial for mock typing.

The current cast hides incompleteness; using Partial<LGraphNode> makes the intent explicit and aligns with test typing conventions.

♻️ Suggested adjustment
-const createMockNode = (overrides: Record<string, unknown> = {}): LGraphNode =>
-  ({
-    id: 1,
-    type: 'TestNode',
-    ...overrides
-  }) as LGraphNode
+const createMockNode = (overrides: Partial<LGraphNode> = {}): LGraphNode =>
+  ({
+    id: 1,
+    type: 'TestNode',
+    ...overrides
+  }) as Partial<LGraphNode> as LGraphNode

Based on learnings, prefer Partial<Interface> casts for incomplete mock objects.

🤖 Fix all issues with AI agents
In `@src/renderer/extensions/vueNodes/components/ImagePreview.vue`:
- Around line 214-218: Hoist the call to the composable out of the event handler
by invoking useMaskEditor() once in the component setup and storing its return
(e.g. const maskEditor = useMaskEditor()) so handleEditMask uses
maskEditor.openMaskEditor(node) instead of calling useMaskEditor() inside the
handler; update the setup block to create maskEditor and ensure handleEditMask
references that variable to avoid missing component instance/injection timing
issues.

@christian-byrne christian-byrne marked this pull request as draft January 18, 2026 04:30
christian-byrne added a commit that referenced this pull request Jan 31, 2026
## Summary
Fix for COM-14110: Preview image does not display new outputs in
vue-nodes.

## Problem
The merge logic in `setOutputsByLocatorId` updated `app.nodeOutputs` but
returned early without updating the reactive `nodeOutputs.value` ref.
This caused Vue components to never receive merged output updates
because only the non-reactive `app.nodeOutputs` was being updated.

## Solution
Added `nodeOutputs.value[nodeLocatorId] = existingOutput` after the
merge loop, before the return statement.

## Testing
- Added 2 unit tests covering the merge behavior
- All 4076 existing unit tests pass
- Typechecks pass
- Lint passes

## Notes
- Related open PRs touching same files: #8143, #8366 - potential minor
conflicts possible

Fixes COM-14110

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8479-fix-update-reactive-ref-after-merge-in-imagePreviewStore-2f86d73d365081f1a145fa5a9782515f)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
github-actions bot pushed a commit that referenced this pull request Jan 31, 2026
## Summary
Fix for COM-14110: Preview image does not display new outputs in
vue-nodes.

## Problem
The merge logic in `setOutputsByLocatorId` updated `app.nodeOutputs` but
returned early without updating the reactive `nodeOutputs.value` ref.
This caused Vue components to never receive merged output updates
because only the non-reactive `app.nodeOutputs` was being updated.

## Solution
Added `nodeOutputs.value[nodeLocatorId] = existingOutput` after the
merge loop, before the return statement.

## Testing
- Added 2 unit tests covering the merge behavior
- All 4076 existing unit tests pass
- Typechecks pass
- Lint passes

## Notes
- Related open PRs touching same files: #8143, #8366 - potential minor
conflicts possible

Fixes COM-14110

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8479-fix-update-reactive-ref-after-merge-in-imagePreviewStore-2f86d73d365081f1a145fa5a9782515f)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
github-actions bot pushed a commit that referenced this pull request Jan 31, 2026
## Summary
Fix for COM-14110: Preview image does not display new outputs in
vue-nodes.

## Problem
The merge logic in `setOutputsByLocatorId` updated `app.nodeOutputs` but
returned early without updating the reactive `nodeOutputs.value` ref.
This caused Vue components to never receive merged output updates
because only the non-reactive `app.nodeOutputs` was being updated.

## Solution
Added `nodeOutputs.value[nodeLocatorId] = existingOutput` after the
merge loop, before the return statement.

## Testing
- Added 2 unit tests covering the merge behavior
- All 4076 existing unit tests pass
- Typechecks pass
- Lint passes

## Notes
- Related open PRs touching same files: #8143, #8366 - potential minor
conflicts possible

Fixes COM-14110

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8479-fix-update-reactive-ref-after-merge-in-imagePreviewStore-2f86d73d365081f1a145fa5a9782515f)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
DrJKL pushed a commit that referenced this pull request Jan 31, 2026
## Summary
Fix for COM-14110: Preview image does not display new outputs in
vue-nodes.

## Problem
The merge logic in `setOutputsByLocatorId` updated `app.nodeOutputs` but
returned early without updating the reactive `nodeOutputs.value` ref.
This caused Vue components to never receive merged output updates
because only the non-reactive `app.nodeOutputs` was being updated.

## Solution
Added `nodeOutputs.value[nodeLocatorId] = existingOutput` after the
merge loop, before the return statement.

## Testing
- Added 2 unit tests covering the merge behavior
- All 4076 existing unit tests pass
- Typechecks pass
- Lint passes

## Notes
- Related open PRs touching same files: #8143, #8366 - potential minor
conflicts possible

Fixes COM-14110

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8479-fix-update-reactive-ref-after-merge-in-imagePreviewStore-2f86d73d365081f1a145fa5a9782515f)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
@DrJKL DrJKL self-assigned this Feb 18, 2026
}

if (props.nodeId) {
nodeOutputStore.syncLegacyNodeImgs(props.nodeId, img, currentIndex.value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing sync always worries me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just doing what happens in litegraph

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does that not comfort me?

) {
if (!LiteGraph.vueNodesMode) return

const node = app.rootGraph?.getNodeById(Number(nodeId))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really need to standardize our NodeId type.

DrJKL
DrJKL previously approved these changes Feb 18, 2026
Copy link
Contributor

@DrJKL DrJKL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this is dirty, but we can clean it up later.

@christian-byrne christian-byrne marked this pull request as ready for review February 18, 2026 08:04
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts (1)

24-27: Prefer centralized TestIds for stable selectors.

The .image-preview, .mask-editor-dialog, and .p-contextmenu class selectors are brittle. Please use the shared TestIds from browser_tests/fixtures/selectors.ts (or add them) for these containers, while keeping text-based assertions for menu items.

As per coding guidelines: Use the centralized TestIds from browser_tests/fixtures/selectors.ts for test element selection.

Also applies to: 38-38, 48-49

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts` around
lines 24 - 27, Replace brittle class-based locators ('.image-preview',
'.mask-editor-dialog', '.p-contextmenu') in imagePreview.spec.ts with the
centralized TestIds exported from browser_tests/fixtures/selectors.ts: import
and use the appropriate TestId constants (e.g., IMAGE_PREVIEW,
MASK_EDITOR_DIALOG, CONTEXT_MENU) when constructing locators for
comfyPage.page.locator(...) or locator(...). Keep menu-item assertions that rely
on visible text unchanged. Update all occurrences mentioned (around the current
checks and the other spots noted) to use these TestId constants so selectors are
stable and consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts`:
- Around line 12-16: The helper loadImageOnNode currently derives the fixture
type from test.info() which is invalid; change its parameter type to the
concrete imported ComfyPage type (import ComfyPage from the fixture module) and
update the function signature to accept comfyPage: ComfyPage. Also replace
class-based DOM selectors ('.image-preview', '.mask-editor-dialog',
'.p-contextmenu') with centralized TestIds (e.g., TestIds.ImagePreview,
TestIds.MaskEditorDialog, TestIds.ContextMenu) by adding those keys to
browser_tests/fixtures/selectors.ts if missing and updating the Vue node
components to expose data-testid attributes that match those TestIds so the spec
uses getByTestId / locator(`[data-testid="${TestIds...}"]`).

---

Nitpick comments:
In `@browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts`:
- Around line 24-27: Replace brittle class-based locators ('.image-preview',
'.mask-editor-dialog', '.p-contextmenu') in imagePreview.spec.ts with the
centralized TestIds exported from browser_tests/fixtures/selectors.ts: import
and use the appropriate TestId constants (e.g., IMAGE_PREVIEW,
MASK_EDITOR_DIALOG, CONTEXT_MENU) when constructing locators for
comfyPage.page.locator(...) or locator(...). Keep menu-item assertions that rely
on visible text unchanged. Update all occurrences mentioned (around the current
checks and the other spots noted) to use these TestId constants so selectors are
stable and consistent.

Comment on lines +12 to +16
async function loadImageOnNode(
comfyPage: Awaited<
ReturnType<(typeof test)['info']>
>['fixtures']['comfyPage']
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and inspect the ComfyPage fixture module
echo "=== ComfyPage fixture file ===" 
fd -a "ComfyPage.ts" browser_tests/fixtures -x head -100 {}

echo -e "\n=== Export patterns in ComfyPage ===" 
fd -a "ComfyPage.ts" browser_tests/fixtures -x rg "export (class|type|interface|const|function|default)" {} -n

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 3648


🏁 Script executed:

#!/bin/bash
# Inspect the imagePreview.spec.ts file around the flagged lines
echo "=== imagePreview.spec.ts (lines 1-30) ===" 
head -50 browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts

echo -e "\n=== Check fixture import and usage ===" 
rg -n "import.*comfyPage|loadImageOnNode|test\.info" browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts -A 3 -B 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2765


🏁 Script executed:

#!/bin/bash
# Check if Playwright TestInfo exposes fixtures through test.info()
# by looking at how fixtures are typically accessed in test files
echo "=== Playwright fixture usage patterns in test files ===" 
rg -r "test\.info\(\)" browser_tests/tests -t ts --max-count=5 -B 2 -A 2

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 984


🏁 Script executed:

#!/bin/bash
# Verify TestIds exports for image preview, mask editor, and context menu
echo "=== TestIds defined in selectors.ts ===" 
rg -n "image|mask|context" browser_tests/fixtures/selectors.ts -i -B 1 -A 1

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 234


🏁 Script executed:

#!/bin/bash
# Check if there are TestIds for image preview or mask editor elsewhere
echo "=== All TestIds entries ===" 
head -100 browser_tests/fixtures/selectors.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2356


🏁 Script executed:

#!/bin/bash
# Check if image preview, mask editor, context menu components have test IDs in source
echo "=== Search for image-preview and mask-editor-dialog in src ===" 
rg "image-preview|mask-editor-dialog" src --include="*.vue" --include="*.ts" -l

echo -e "\n=== Check context menu component ===" 
rg "p-contextmenu|ContextMenu" src --include="*.vue" --include="*.ts" -l | head -5

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1071


🏁 Script executed:

#!/bin/bash
# Check if image preview, mask editor, context menu components have test IDs in source
echo "=== Search for image-preview in src ===" 
rg "image-preview" src -t vue -t ts

echo -e "\n=== Search for mask-editor-dialog ===" 
rg "mask-editor-dialog" src -t vue -t ts

echo -e "\n=== Search for p-contextmenu ===" 
rg "p-contextmenu" src -t vue -t ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 283


🏁 Script executed:

#!/bin/bash
# Check if image preview, mask editor, context menu components have test IDs in source
echo "=== Search for image-preview in src ===" 
rg "image-preview" src

echo -e "\n=== Search for mask-editor-dialog ===" 
rg "mask-editor-dialog" src

echo -e "\n=== Search for p-contextmenu ===" 
rg "p-contextmenu" src

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1163


🏁 Script executed:

#!/bin/bash
# Verify what's accessible on the comfyPageFixture object
echo "=== comfyPageFixture definition ===" 
rg -n "comfyPageFixture = base.extend" browser_tests/fixtures/ComfyPage.ts -A 20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 974


Fixture type derivation is invalid; use the imported ComfyPage type directly.

Playwright TestInfo (from test.info()) doesn't expose a fixtures property, making the type path inaccessible. Import and use the concrete ComfyPage type instead.

Additionally, use centralized TestIds for element selection instead of class-based selectors (.image-preview, .mask-editor-dialog, .p-contextmenu). If TestIds doesn't have entries for these Vue node components yet, add them to browser_tests/fixtures/selectors.ts and update the components to use data-testid attributes.

✅ Proposed fix for fixture type
 import { expect } from '@playwright/test'
 
 import { comfyPageFixture as test } from '../../../../fixtures/ComfyPage'
+import type { ComfyPage } from '../../../../fixtures/ComfyPage'
 
   async function loadImageOnNode(
-    comfyPage: Awaited<
-      ReturnType<(typeof test)['info']>
-    >['fixtures']['comfyPage']
+    comfyPage: ComfyPage
   ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@browser_tests/tests/vueNodes/interactions/node/imagePreview.spec.ts` around
lines 12 - 16, The helper loadImageOnNode currently derives the fixture type
from test.info() which is invalid; change its parameter type to the concrete
imported ComfyPage type (import ComfyPage from the fixture module) and update
the function signature to accept comfyPage: ComfyPage. Also replace class-based
DOM selectors ('.image-preview', '.mask-editor-dialog', '.p-contextmenu') with
centralized TestIds (e.g., TestIds.ImagePreview, TestIds.MaskEditorDialog,
TestIds.ContextMenu) by adding those keys to browser_tests/fixtures/selectors.ts
if missing and updating the Vue node components to expose data-testid attributes
that match those TestIds so the spec uses getByTestId /
locator(`[data-testid="${TestIds...}"]`).

- Fix createPinia() → createTestingPinia() (merge conflict artifact)
- Fix 'should return empty string if output is animated' test to mock
  isAnimatedOutput instead of setting node property
- Hoist useMaskEditor() to component setup (CodeRabbit review)
- Use as unknown as LGraphNode for clearer mock typing

Amp-Thread-ID: https://ampcode.com/threads/T-019c730f-b5f6-713f-87c2-4f39d4eb6cf5
@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.39 Backport PRs for core 1.39 cloud/1.39 Backport PRs for cloud 1.39 labels Feb 19, 2026
@christian-byrne christian-byrne merged commit 27d4a34 into main Feb 19, 2026
37 of 38 checks passed
@christian-byrne christian-byrne deleted the fix/sync-node-imgs-legacy-context-menu branch February 19, 2026 00:34
github-actions bot pushed a commit that referenced this pull request Feb 19, 2026
## Summary

Fixes missing "Copy Image", "Open Image", "Save Image", and "Open in
Mask Editor" context menu options on SaveImage nodes when Vue Nodes mode
is enabled.

## Changes

- Add `syncLegacyNodeImgs` store method to sync loaded image elements to
`node.imgs`
- Call sync on image load in ImagePreview component
- Simplify mask editor handling to call composable directly

## Technical Details

- Only runs when `vueNodesMode` is enabled (no impact on legacy mode)
- Reuses already-loaded `<img>` element from Vue (no duplicate network
requests)
- Store owns the sync logic, component just hands off the element

Supersedes #7416

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8143-fix-sync-node-imgs-for-legacy-context-menu-in-Vue-Nodes-mode-2ec6d73d365081c59d42cd1722779b61)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
github-actions bot pushed a commit that referenced this pull request Feb 19, 2026
## Summary

Fixes missing "Copy Image", "Open Image", "Save Image", and "Open in
Mask Editor" context menu options on SaveImage nodes when Vue Nodes mode
is enabled.

## Changes

- Add `syncLegacyNodeImgs` store method to sync loaded image elements to
`node.imgs`
- Call sync on image load in ImagePreview component
- Simplify mask editor handling to call composable directly

## Technical Details

- Only runs when `vueNodesMode` is enabled (no impact on legacy mode)
- Reuses already-loaded `<img>` element from Vue (no duplicate network
requests)
- Store owns the sync logic, component just hands off the element

Supersedes #7416

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8143-fix-sync-node-imgs-for-legacy-context-menu-in-Vue-Nodes-mode-2ec6d73d365081c59d42cd1722779b61)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #8969

@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #8970

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Feb 19, 2026
DrJKL pushed a commit that referenced this pull request Feb 19, 2026
)

Mark the two browser tests added in #8143 as `test.fixme` — they are
failing on main.

- `opens mask editor from image preview button`
- `shows image context menu options`

- Fixes #8143 (browser test failures)

---------

Co-authored-by: GitHub Action <action@github.com>
christian-byrne added a commit that referenced this pull request Feb 20, 2026
The tests from PR #8143 were written against stale ComfyPage APIs
that were refactored in PR #8510:
- comfyPage.dragAndDropFile → comfyPage.dragDrop.dragAndDropFile
- comfyPage.setSetting → comfyPage.settings.setSetting
- comfyPage.loadWorkflow → comfyPage.workflow.loadWorkflow
- comfyPage.getNodeRefsByType → comfyPage.nodeOps.getNodeRefsByType
- comfyPage type param → import ComfyPage type directly

Also removes test.fixme since the root cause was API mismatch.

Amp-Thread-ID: https://ampcode.com/threads/T-019c73c1-be32-7687-b758-672fedaf61af
christian-byrne added a commit that referenced this pull request Feb 20, 2026
The tests from PR #8143 were written against stale ComfyPage APIs
that were refactored in PR #8510:
- comfyPage.dragAndDropFile → comfyPage.dragDrop.dragAndDropFile
- comfyPage.setSetting → comfyPage.settings.setSetting
- comfyPage.loadWorkflow → comfyPage.workflow.loadWorkflow
- comfyPage.getNodeRefsByType → comfyPage.nodeOps.getNodeRefsByType
- comfyPage type param → import ComfyPage type directly

Also removes test.fixme since the root cause was API mismatch.

Amp-Thread-ID: https://ampcode.com/threads/T-019c73c1-be32-7687-b758-672fedaf61af
christian-byrne added a commit that referenced this pull request Feb 20, 2026
The tests from PR #8143 were written against stale ComfyPage APIs
that were refactored in PR #8510:
- comfyPage.dragAndDropFile → comfyPage.dragDrop.dragAndDropFile
- comfyPage.setSetting → comfyPage.settings.setSetting
- comfyPage.loadWorkflow → comfyPage.workflow.loadWorkflow
- comfyPage.getNodeRefsByType → comfyPage.nodeOps.getNodeRefsByType
- comfyPage type param → import ComfyPage type directly

Also removes test.fixme since the root cause was API mismatch.

Amp-Thread-ID: https://ampcode.com/threads/T-019c73c1-be32-7687-b758-672fedaf61af
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud/1.39 Backport PRs for cloud 1.39 core/1.39 Backport PRs for core 1.39 size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants